-------------------------------------------------------------------------------
---! 内部方法
-------------------------------------------------------------------------------
---! 给与关卡奖励
local function give_stage_award(player, stage_level)
    local configs = IMPORT_D:query("stageaward")
    if not configs then
        return
    end

    local config = configs[stage_level]
    if not config then
        return
    end

    local award_type = config.type
    if not award_type then
        return
    end

    if award_type == 1 then
        ---! 货币类型奖励
        player:add_currency(config.award, config.awardNum)

        ---! 刷新货币信息
        -- ITEM_D:send_currency_info(player)
        return
    end

    if award_type == 2 then
        ---! 伙伴类型奖励
        player:add_partner(config.award)

        ---! 发送伙伴信息
        PARTNER_D:send_partner_info(player)

        ---! 同步伙伴排名
        RANK_D:sync_rank_data(player, "partner_rank")
        return
    end
end

---! 查找怪物配置
local function find_monster(monster_id)
    local configs = IMPORT_D:query("monster")
    if not configs then
        return
    end

    local config = configs[monster_id]
    if not config then
        return
    end

    return config
end

---! 查找怪物列表
local function find_monster_map(monster_level, round)
    local configs = IMPORT_D:query("stage")
    if not configs then
        return
    end

    local config = configs[monster_level]
    if not config then
        return
    end

    if #config < round + 1 then
        return
    end

    local monster_map = config[round + 1]
    if not monster_map then
        return
    end

    return monster_map
end

---! 查找怪物掉落
local function find_monster_drop(monster_level)
    local configs = IMPORT_D:query("monsterdrop")
    if not configs then
        return
    end

    local config = configs[monster_level]
    if not config then
        return
    end

    return config
end

---! 获取指定关卡总回合数
local function get_stage_total_round(stage_level)
    local configs = IMPORT_D:query("stage")
    if not configs then
        return 0
    end

    local config = configs[stage_level]
    if not config then
        return 0
    end

    return #config
end

---! 获取翅膀收益
local function get_wing_profit(player)
    local wingid = player:get_use_wing()
    if wingid <= 0 then
        return 0
    end

    local winglev = player:get_wing_level(wingid)
    local wingconfig = WING_D:find_wing(wingid, winglev)
    if not wingconfig then
        return 0
    end

    ---! 有且仅有法源神翅才有杀怪收益
    if wingconfig.wingid ~= WingTable.kGameWingThree then
        return 0
    end

    return wingconfig.num1
end

---! 获取装备收益
local function get_equip_profit(player)
    local num = 0
    for _, equip in pairs(player:get_equip()) do
        if equip.attribute == "money" then
            num = num + equip.num
        end
    end
    return num
end

-------------------------------------------------------------------------------
---! 对外接口
-------------------------------------------------------------------------------
STAGE_D = {}

---! 开启关卡
function STAGE_D:start_stage(player, stage_level)
    if not stage_level then
        return
    end

    local cur_stage_level = player:get_stage_level()
    if cur_stage_level - 1 == stage_level then
        ---! 记录训练关卡
        player:set_temp("train_stage_level", stage_level)

        ---! 重置当前关卡
        player:start_new_round()

        ---! 复活所有伙伴
        player:rescue_all_partners()

        local result = {}
        result.code = 200
        result.ret = true
        player:send_packet("MSGS2CPassStage", result)
        return
    end

    if cur_stage_level == stage_level then
        ---! 清除训练关卡
        player:delete_temp("train_stage_level")

        ---! 重置当前关卡
        player:start_new_round()

        ---! 复活所有伙伴
        player:rescue_all_partners()

        local result = {}
        result.code = 200
        result.ret = true
        player:send_packet("MSGS2CPassStage", result)
        return
    end

    if cur_stage_level + 1 == stage_level and
        player:get_stage_round() >= get_stage_total_round(cur_stage_level) then
        ---! 开始新的关卡
        player:start_new_stage(stage_level)

        ---! 复活所有伙伴
        player:rescue_all_partners()

        ---! 给予关卡奖励
        give_stage_award(player, cur_stage_level)

        local result = {}
        result.code = 200
        result.ret = true
        player:send_packet("MSGS2CPassStage", result)

        ---! 同步关卡排名
        RANK_D:sync_rank_data(player, "stage_rank")

        ---! 尝试初始翅膀
        WING_D:init_wing_info(player)

        ---! 尝试解锁翅膀
        WING_D:unlock_wing_by_stage(player, stage_level)

        ---! 同步翅膀排名
        RANK_D:sync_rank_data(player, "wings_rank")

        ---! 尝试初始神器
        ARTIFACT_D:init_artifact_info(player)

        ---! 尝试解锁神器
        ARTIFACT_D:unlock_artifact_by_stage(player, stage_level)

        ---! 同步神器排名
        RANK_D:sync_rank_data(player, "artifact_rank")

        ---! 刷新货币信息
        ITEM_D:send_currency_info(player)
        return
    end

    local result = {}
    result.code = 400
    result.ret = false
    result.msg = "pass stage level error"
    player:send_packet("MSGS2CPassStage", result)
end

function STAGE_D:kill_monsters(player, monster_ids, isbuff)
    if #monster_ids < 1 then
        return
    end

    local stage_time = player:query_temp("stage", "time")
    if stage_time then
        if os.time() - stage_time < 1 then
            local result = {}
            result.ret = false
            result.msg = string.format("stage_time: %d now_time: %d, kill monsters too quick.", stage_time, os.time())
            player:send_packet("MSGS2CKillMonster", result)
            return
        end
    end

    ---! 获取当前关卡等级
    local stage_level = player:query_temp("train_stage_level")
    if not stage_level then
        stage_level = player:get_stage_level()
    end

    ---! 获取当前关卡回合数
    local stage_round = player:get_stage_round()

    ---! 获取怪物列表
    local monster_map = find_monster_map(stage_level, stage_round)
    if not monster_map then
        local result = {}
        result.ret = false
        result.msg = string.format("Level: %d Round: %d, config not exist", stage_level, stage_round)
        player:send_packet("MSGS2CKillMonster", result)
        return
    end

    ---! 获取击杀列表
    local dead_monster_map = {}
    local kill_monster_map = player:get_stage_monster()
    for _, monster_id in ipairs(monster_ids) do
        local monster = find_monster(monster_id)
        if not monster then
            local result = {}
            result.ret = false
            result.msg = "monster config not exist"
            player:send_packet("MSGS2CKillMonster", result)
            return
        end

        local monster_count = monster_map[monster_id]
        if not monster_count then
            local result = {}
            result.ret = false
            result.msg = string.format("Level: %d Round: %d, monster id [%s] not in monster list", stage_level, stage_round, monster_id)
            player:send_packet("MSGS2CKillMonster", result)
            return
        end

        local dead_count = dead_monster_map[monster_id] or 0
        local kill_count = kill_monster_map[monster_id] or 0
        if kill_count + dead_count >= monster_count then
            local result = {}
            result.ret = false
            result.msg = "monster killed count is too enough"
            player:send_packet("MSGS2CKillMonster", result)
            return
        end

        dead_monster_map[monster_id] = (dead_monster_map[monster_id] or 0) + 1
    end

    ---! 累加击杀次数
    for monster_id, monster_count in pairs(dead_monster_map) do
        kill_monster_map[monster_id] = (kill_monster_map[monster_id] or 0) + monster_count
    end

    ---! 获取翅膀收益
    local wing_profit = get_wing_profit(player)

    ---! 获取装备收益
    local equip_profit = get_equip_profit(player)

    ---! 铜钱收益
    local coin_profit = (isbuff > 0 and 10.0 or 1.0) + wing_profit + equip_profit

    ---! 灵魂收益
    local soul_profit = 1.0 + wing_profit + equip_profit

    ---! 获取相关掉落
    local coin, soul = 0, 0
    local monster_drop = find_monster_drop(stage_level)
    if monster_drop then
        for monster_id, monster_count in pairs(dead_monster_map) do
            local monster = find_monster(monster_id)
            if monster then
                ---! 掉落钱币 * 掉落钱币系数
                coin = coin + math.floor(coin_profit * monster_drop.dropCoin * monster.dropCoin) * monster_count

                ---! 掉落灵魂 * 掉落灵魂系数
                soul = soul + math.floor(soul_profit * monster_drop.dropSoul * monster.dropSoul) * monster_count
            end
        end
    end

    ---! 给与相应的钱币与灵魂
    if coin > 0 or soul > 0 then
        player:add_currency(GamePropIds.kGamePropIdsCopperIcon, coin)
        player:add_currency(GamePropIds.kGamePropIdsSoulIcon, soul)
        ITEM_D:send_currency_info(player)
    end

    ---! 不产生掉落，直接回复消息
    local result = {}
    result.ret = true
    player:send_packet("MSGS2CKillMonster", result)

    ---! 尝试更新回合数，即进入下一回合
    for monster_id, monster_count in pairs(monster_map) do
        local kill_count = kill_monster_map[monster_id]
        if not kill_count then
            return
        end

        if kill_count < monster_count then
            return
        end
    end

    player:start_new_round(stage_round + 1)
end
